//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2016/12/27 15:16:27
// Design Name: Chongyaoxu
// Module Name: reg_ahb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
// Top module for SM3 Algorithm

`timescale 1ns/10ps

// The initial value 
`define IV_0 32'h7380166f
`define IV_1 32'h4914b2b9
`define IV_2 32'h172442d7
`define IV_3 32'hda8a0600
`define IV_4 32'ha96f30bc
`define IV_5 32'h163138aa
`define IV_6 32'he38dee4d
`define IV_7 32'hb0fb0e4e

// The value for parameter Tj 
`define T0 32'h79cc4519    //  0  <= j <= 15
`define T1 32'h9d8a7a87    //  16 <= j <= 63

`define idle        'b00                //idle state, no operation
`define write       'b01	            // write register 
`define encryption  'b10	    // encryption only
`define sta_finish        'b11		    	// read register
//module SM3_reg_ahb ( clk , rst , write , read ,mes_in , result_out , state ,finish );
module SM3_reg_ahb ( input clk , input rst , input [31:0] control ,output reg [31:0] status ,
input [31:0]    msg_in1 ,msg_in2  ,msg_in3  ,msg_in4  ,msg_in5  ,msg_in6  ,msg_in7  ,msg_in8  ,
input [31:0]    msg_in9 ,msg_in10 ,msg_in11 ,msg_in12 ,msg_in13 ,msg_in14 ,msg_in15 ,msg_in16 , 
output [31:0]   msg_out1,msg_out2 ,msg_out3 ,msg_out4 ,msg_out5 ,msg_out6 ,msg_out7 ,msg_out8  );

//parameter idle='b00;                //idle state, no operation
//parameter write = 'b01;	            // write register 
//parameter encryption = 'b10;	    // encryption only
//parameter read = 'b11;		    	// read register

wire [1:0]state;
reg [31:0] mes_in;
wire finish ;
reg write_trig;            //Detect write signal
reg W;                     //SM3 write signal
reg R;                     //SM3 read signal

wire [6:0] round ;
always@(*)begin
    if(control[5])begin
        mes_in = 32'b0;
    end
    else if(state == `write)begin
        case ( round )
            'd0 :  mes_in =  msg_in1;
            'd1 :  mes_in =  msg_in2;
            'd2 :  mes_in =  msg_in3;
            'd3 :  mes_in =  msg_in4;
            'd4 :  mes_in =  msg_in5;
            'd5 :  mes_in =  msg_in6;
            'd6 :  mes_in =  msg_in7;
            'd7 :  mes_in =  msg_in8;
            'd8 :  mes_in =  msg_in9;
            'd9 :  mes_in =  msg_in10;
            'd10 :  mes_in =  msg_in11;
            'd11 :  mes_in =  msg_in12;
            'd12 :  mes_in =  msg_in13;
            'd13 :  mes_in =  msg_in14;
            'd14 :  mes_in =  msg_in15;
            'd15 :  mes_in =  msg_in16;   
            default: mes_in =  32'b0;
        endcase
    end
    else
         mes_in =  32'b0;
end

always@(posedge clk or negedge rst)begin
    if(!rst)begin
        W <= 'b0;
        R <= 'b0;  
        write_trig <= 'b0;  
    end
    else if(control[5])begin
        W <= 'b0;
        R <= 'b0;
        write_trig <= 'b0;
    end
    else if( !control[3] )begin
        W <= 'b0;
        R <= 'b1;
    end
    else if(control[4])begin
        W <= 'b0;
        R <= 'b0;
        write_trig <= 'b0;
    end
    else if( (!control[4]) && (write_trig == 'b0) )begin
        W <= 'b1;
        R <= 'b0;
        write_trig <= 'b1;
    end
    else if( (round>'d16) && (round<'d69) )begin
        W <= 'b0;
        R <= 'b0;
    end
    else begin
        W <= W;
        R <= R;
    end
end

always@(posedge clk or negedge rst)begin
    if(!rst)begin
        status <= 32'b0;
    end
    else if(control[5])begin
        status <= 32'b0;
    end
    else if(finish == 1)begin       //compute finish
        status <= `sta_finish;
    end
    else if( (status != `sta_finish)||(control[4]) )begin
        if(state == `idle)begin
            status <= 32'b0;
        end
        else if(state == `write)begin
            status <= 32'b01;
        end
        else if(state == `encryption)begin
            status <= 32'b10;
        end
        else
            status <= 32'b0;
    end
    else
        status <= status;
end
//Reading Module control= 'b001
//Read_Message rm1 (.clk(Clk) , .rst(Rst) , .ctrl(State) , .mes_in(Mes_in) , .Mes_out(message) , .Mes_length(mlength));
//Read_Message rm1(Clk , Rst , Mes_in , message , mlength) ;
//Control module
SM3_Controller SC1 (.clk(clk) , .rst(rst)  , .W(W) , .R(R) , .count_out(round) , .ctrl(state) , .finish(finish));

//message extend and compress
CompressExtend me1 (.clk(clk) , .rst(rst) , .ctrl(state) , .finish(finish) , .m_i(mes_in) , .Round(round) , 
    .wout({msg_out8,msg_out7,msg_out6,msg_out5,msg_out4,msg_out3,msg_out2,msg_out1})
    );

endmodule

